#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#include <cstdlib>

// 共享资源
int shared_data = 0;

// 读写锁
pthread_rwlock_t rwlock;

void* Reader(void* args) {
    // sleep(2); // 读者优先，一旦读者进入，写者就很难进入了
    const char* name = static_cast<const char*>(args);
    while (true) {
        pthread_rwlock_rdlock(&rwlock);
        std::cout << name << " is reading the shared data, the data is " << shared_data << std::endl;
        sleep(1); // 模拟读花的时间
        pthread_rwlock_unlock(&rwlock);
    }
    return nullptr;
}

void* Writer(void* args) {
    const char* name = static_cast<const char*>(args);
    while (true) {
        pthread_rwlock_wrlock(&rwlock);
        shared_data = rand() % 100;
        std::cout << name << " is writing the shared data, the data is " << shared_data << std::endl; 
        sleep(1); // 模拟写花的时间
        pthread_rwlock_unlock(&rwlock);
    }
    return nullptr;
}

int main() {
    srand(time(nullptr) ^ getpid());
    pthread_rwlock_init(&rwlock, nullptr);
    const int reader_num = 2;
    const int writer_num = 2;
    const int total = reader_num + writer_num;
    pthread_t threads[total]; 
    // 创建读线程
    for (int i = 0; i < reader_num; i++) {
        char* buff = new char[128];
        snprintf(buff, 128, "reader-%d", i + 1);
        pthread_create(&threads[i], nullptr, Reader, (void*)buff);
    }

    // 创建写线程
    for (int i = reader_num; i < total; i++) {
        char* buff = new char[128];
        snprintf(buff, 128, "writer-%d", i + 1);
        pthread_create(&threads[i], nullptr, Writer, (void*)buff);
    }

    for (int i = 0; i < total; i++) {
        pthread_join(threads[i], nullptr);
    }

    pthread_rwlock_destroy(&rwlock);
    return 0;
}

struct Protocal {
    int a;
    int b;
    int c;
};

// pthread_spinlock_t lock;
// int tickets = 1000;

// void* Routine(void* args) {
//     const char* name = static_cast<const char*>(args);
    
//     while (true) {
//         pthread_spin_lock(&lock);
//         if (tickets > 0) {
//             usleep(1000); // 表示抢票时间
//             std::cout << name << " get a ticket, the remaining tickets are: " << tickets << std::endl;
//             tickets--;
//             pthread_spin_unlock(&lock);
//         } else {
//             pthread_spin_unlock(&lock);
//             break;
//         }
//     }

//     return nullptr;
// }

// int main() {
//     pthread_spin_init(&lock, 0);
//     pthread_t t1, t2, t3, t4;
    
//     pthread_create(&t1, nullptr, Routine, (void*)"thread-1");
//     pthread_create(&t2, nullptr, Routine, (void*)"thread-1");
//     pthread_create(&t3, nullptr, Routine, (void*)"thread-1");
//     pthread_create(&t4, nullptr, Routine, (void*)"thread-1");

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);
//     pthread_join(t4, nullptr);

//     pthread_spin_destroy(&lock);
//     return 0;
// }



// // 加锁
// lock(count_lock);
// // 当第一个读者进来的时候，要将写者锁住
// if(reader_count == 0)
//     lock(writer_lock);
// ++reader_count;
// unlock(count_lock);

// //解锁
// lock(count_lock);
// --reader_count;
// // 当是最后一个读者离开的时候，将写者唤醒，让写者写入信息
// if(reader_count == 0)
//     unlock(writer_lock);
// unlock(count_lock);


// lock(writer_lock);
// // write
// unlock(writer_lock);

// typedef _Atomic struct
// {
// #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
// _Bool __val;
// #else
// unsigned char __val;
// #endif
// } atomic_flag;

// atomic_flag spinlock = ATOMIC_FLAG_INIT;

// // 尝试获取锁
// void spinlock_lock() {
//     // 没有获取到锁则一直运行，返回值为true
//     // 获取到锁，返回值为false，跳出循环等待
//     while (atomic_flag_test_and_set(&spinlock)) {
//     // 如果锁被占用，则忙等待
//     }
// }

// // 释放锁
// void spinlock_unlock() {
//     atomic_flag_clear(&spinlock);
// }